package test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class ExtraiXML {

	public static void main(String[] args) {

		int numeroCampos = Integer.parseInt(args[0]);
		int tamanhoHierarquia = Integer.parseInt(args[1]);
		int tamanhoCampos = Integer.parseInt(args[2]);
		
		/*int numeroCampos = 5;
		int tamanhoHierarquia = 500;
		int tamanhoCampos = 5;*/
		
		
		String extracao = "";

		try {

			String xmlPayload = ExtraiXML.getXml(tamanhoCampos, numeroCampos,
					tamanhoHierarquia);
			
			long start = new Date( ).getTime( );//marca tempo
			
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer t = tf.newTransformer();
			
			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			Document doc = docBuilder.parse(new ByteArrayInputStream(xmlPayload
					.getBytes()));
			doc.normalize();

			// start extraction
			Element root = doc.getDocumentElement();
			Element element = root;
			int index = 1;

			while (element != null && element.hasChildNodes()) {
				index++;
				String nodeName = element.getNodeName();
				extracao = extracao + nodeName  + " =  " + ExtraiXML.xmlToString(element, t) + "\n";
				element = (Element) element.getElementsByTagName("obj" + index).item(0);
			}

			element = (Element) root.getElementsByTagName("obj" + --index).item(0);
			index = 0;
			
			while (null != element.getElementsByTagName("campo" + ++index).item(0)) {
				Element campo = (Element) element.getElementsByTagName("campo" + index).item(0);
				String nodeName = campo.getNodeName();
				String nodeValue = campo.getTextContent();
				extracao = extracao + nodeName + " = " + nodeValue + "\n";
			}
			
			long end = new Date().getTime();
			System.out.println(end - start);
		} catch (ParserConfigurationException e) {
			System.out.println("error on document builder");
		} catch (SAXException e) {
			e.printStackTrace();
			System.out.println("error on xml document");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("error on xml document");
		} catch (TransformerConfigurationException e) {
			System.out.println("error on xml transformer");
		}

	}

	private static String getXml(int tamanhoCampos, int numeroCampos,
			int tamanhoHierarquia) {

		String xml = "";

		String valorCampo = "";

		try {
			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			Document doc = docBuilder.newDocument();

			Element rootElement = doc.createElement("obj" + tamanhoHierarquia);
			Element tempElement;

			for (int i = 1; i <= numeroCampos; i++) {
				for (int j = 1; j <= tamanhoCampos; j++) {
					valorCampo += "a";
				}
				tempElement = doc.createElement("campo" + i);
				tempElement.setTextContent(valorCampo);

				rootElement.appendChild(tempElement);
				valorCampo = "";
			}

			for (int i = tamanhoHierarquia - 1; i >= 1; i--) {
				tempElement = doc.createElement("obj" + i);
				tempElement.appendChild(rootElement);
				rootElement = tempElement;
			}

			doc.appendChild(rootElement);

			TransformerFactory tf = TransformerFactory.newInstance();
			try {
				Transformer t = tf.newTransformer();
				DOMSource source = new DOMSource(doc);
				StringWriter sw = new StringWriter();
				StreamResult result = new StreamResult(sw);
				t.transform(source, result);
				xml = sw.toString();
			} catch (TransformerConfigurationException e) {
				e.printStackTrace();
			} catch (TransformerException e) {
				e.printStackTrace();
			}
		} catch (ParserConfigurationException e) {
			System.out.println("error on document builder");
		}

		return xml;
	}
	
	private static String xmlToString(Element element, Transformer t){
		String xml = "";
		
		try {
			DOMSource source = new DOMSource(element);
			StringWriter sw = new StringWriter();
			StreamResult result = new StreamResult(sw);
			t.transform(source, result);
			xml = sw.toString();
		} catch (TransformerException e) {
			e.printStackTrace();
		}
		return xml;
				
	}
}
